package com.home.auto_navigation.common;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import com.home.auto_navigation.common.api.NoSuchWayException;
import com.home.auto_navigation.ui.AbstractPageObject;

public class ShortWay {

    public static List<Class<? extends AbstractPageObject>> getShortWay(
            Class<? extends AbstractPageObject> pageStart,
            Class<? extends AbstractPageObject> pageEnd) {
        try {
            if (pageStart.equals(pageEnd))
                return null;
            List<Class<? extends AbstractPageObject>> way;
            // list for pages which was visited
            List<Class<? extends AbstractPageObject>> used = new ArrayList<>();
            // list of pages that are currently browsing
            LinkedList<Class<? extends AbstractPageObject>> currentlyPages = new LinkedList<>();
            // Map for to save a previous page
            Map<Class<? extends AbstractPageObject>, Class<? extends AbstractPageObject>> previous = new HashMap<>();
            used.add(pageStart);
            previous.put(pageStart, null);
            currentlyPages.add(pageStart);
            while (!currentlyPages.isEmpty()) {
                Class<? extends AbstractPageObject> page = currentlyPages
                        .getFirst();
                currentlyPages.removeFirst();
                List<Class<? extends AbstractPageObject>> listPages = SiteMap.getInstance().getMap().get(page);
                for (int i = 0; i < listPages.size(); ++i) {
                    Class<? extends AbstractPageObject> pageTo = listPages
                            .get(i);
                    if (!used.contains(pageTo)) {
                        used.add(pageTo);
                        currentlyPages.add(pageTo);
                        previous.put(pageTo, page);
                        if (pageTo.equals(pageEnd)) {
                            // algorithm for constructing the way
                            way = new LinkedList<Class<? extends AbstractPageObject>>();
                            way.add(pageTo);
                            do {
                                Class<? extends AbstractPageObject> previousPage = previous
                                        .get(pageTo);
                                way.add(previousPage);
                                pageTo = previousPage;
                            } while (previous.get(pageTo) != null);
                            Collections.reverse(way);
                            return way;
                        }
                    }
                }
            }

            throw new NoSuchWayException("way from "
                    + pageStart.getSimpleName() + " to "
                    + pageEnd.getSimpleName() + " does not exist");
        } catch (NoSuchWayException e) {
            e.printStackTrace();
            // getDriver().get(Config.getProperty("url"));
            // getShortWay(HomePage.class, pageEnd);
        }
        return null;
    }
}
